<template>
  <ProTable
    ref="tableRef"
    :fetchListApi="_getList"
    :columns="columns"
    :row-selection="rowSelection"
    row-key="id"
  >
    <template #toolbars>
      <Space>
        <b-button
          icon="add"
          @click="onRegistered"
          code="bulkRegistration:batch:submit"
          >批量注册</b-button
        >
        <b-button
          icon="edit"
          :disabled="!selectKeys.length"
          @click="onMerge"
          code="bulkRegistration:merge"
          >合并</b-button
        >
        <b-button
          icon="delete"
          :disabled="!selectKeys.length"
          @click="onDelete"
          code="bulkRegistration:remove"
          >删除</b-button
        >
      </Space>
    </template>
    <template #operation="{ record }">
      <b-button
        type="link"
        icon="detail"
        @click="onView(record)"
        code="bulkRegistration:query"
        >详情</b-button
      >
      <b-button
        type="link"
        icon="detail"
        @click="onRecord(record)"
        code="bulkRegistration:log"
        >下发记录</b-button
      >
    </template>
  </ProTable>

  <FormModal :items="items">
    <template #details>
      <div class="details">
        <ProTable
          ref="tableRef"
          hideSearch
          :fetchListApi="_getPushTotalInfo"
          :columns="_columns"
        >
          <template #publishRate="{ record }">
            {{
              record.publishRate
                ? record.publishRate * 100 + '%'
                : record.publish
            }}
          </template>
          <template #operation="{ record }">
            <b-button type="link" icon="detail" @click="onDetail(record)"
              >查看详情</b-button
            >
          </template>
        </ProTable>
      </div>
    </template>
  </FormModal>

  <FormModal2 :items="items">
    <template #details>
      <div class="details">
        <ProTable
          ref="tableRef"
          hideSearch
          :fetchListApi="_getRecordList"
          :columns="_recordColumns"
        >
          <template #pushStatus="{ record }">
            <div>
              <span
                :style="{
                  color: record.pushStatus === '1' ? '#67c23a' : '#f56c6c',
                }"
                >{{ record.pushStatus === '1' ? '成功' : '失败' }}</span
              >
            </div>
          </template>

          <template #onlineStatus="{ record }">
            <div>
              <span
                :style="{
                  color: record.onlineStatus === '1' ? '#67c23a' : '#f56c6c',
                }"
                >{{ record.onlineStatus === '1' ? '在线' : '离线' }}</span
              >
            </div>
          </template>
        </ProTable>
      </div>
    </template>
  </FormModal2>

  <FormModal3 :items="items">
    <template #details>
      <div class="record_detail">
        <FormItemRest>
          <ProTable
            ref="detailRef"
            :fetchListApi="_getRegisterInfo"
            :columns="_importColumns"
            :row-selection="codeSelection"
            row-key="code"
          >
            <template #expandedRowRender="{ record }">
              <Descriptions :column="2" :labelStyle="contentStyle">
                <DescriptionsItem label="客户端ID">{{
                  record.mqttClientId || '-'
                }}</DescriptionsItem>
                <DescriptionsItem label="群组ID">{{
                  record.groupId || '-'
                }}</DescriptionsItem>
                <DescriptionsItem label="服务地址">{{
                  record.mqttIp || '-'
                }}</DescriptionsItem>
                <DescriptionsItem label="服务端口">{{
                  record.mqttPort || '-'
                }}</DescriptionsItem>
                <DescriptionsItem label="用户名">{{
                  record.mqttAccount || '-'
                }}</DescriptionsItem>
                <DescriptionsItem label="密码">{{
                  record.mqttPassword || '-'
                }}</DescriptionsItem>
                <DescriptionsItem label="预警主题">{{
                  record.subscribedTopicWarning || '-'
                }}</DescriptionsItem>
                <DescriptionsItem label="预警回复">{{
                  record.ackTopicWarning || '-'
                }}</DescriptionsItem>
                <DescriptionsItem label="速报主题">{{
                  record.subscribedTopicReport || '-'
                }}</DescriptionsItem>
                <DescriptionsItem label="演练主题订阅地址">{{
                  record.subscribedTopicDrillWarning || '-'
                }}</DescriptionsItem>
              </Descriptions>
            </template>

            <template #toolbars>
              <Space>
                <b-button
                  :disabled="!codeKeys.length"
                  v-if="registerStatus === '1'"
                  @click="handleSend"
                  >下发配置</b-button
                >
                <b-button
                  :disabled="!codeKeys.length"
                  v-if="registerStatus === '1'"
                  @click="handlePushCompare"
                  >下发对比</b-button
                >
                <b-button
                  :disabled="!codeKeys.length"
                  v-if="registerStatus === '0'"
                  @click="handleClickRescue(true)"
                  >注册救济</b-button
                >
              </Space>
              <Space>
                <div
                  :class="['success', { active: registerStatus == '1' }]"
                  @click="onChange('1')"
                >
                  注册成功
                </div>
                <div
                  :class="['error', { active: registerStatus == '0' }]"
                  @click="onChange('0')"
                >
                  注册失败
                </div>
              </Space>
            </template>

            <template #registerStatus="{ record }">
              <span v-if="record.registerStatus == '0'" style="color: #67c23a"
                >成功</span
              >
              <span v-else style="color: #f56c6c">失败</span>
            </template>

            <template #onlineStatus="{ record }">
              <span v-if="record.onlineStatus == '1'" style="color: #67c23a"
                >在线</span
              >
              <span v-else style="color: #f56c6c">离线</span>
            </template>

            <template #contrastStatus="{ record }">
              <span v-if="record.contrastStatus == '0'" style="color: #67c23a"
                >比对正确</span
              >
              <span
                v-else-if="record.contrastStatus == '1'"
                style="color: #f56c6c"
                >信息不对</span
              >
              <span v-else style="color: #f56c6c">未比对</span>
            </template>
          </ProTable>
        </FormItemRest>
      </div>
    </template>
  </FormModal3>

  <FormModal4 :items="items">
    <template #customFooter="{ visible }">
      <template v-if="isSuccess">
        <b-button
          @click="handleClickRescue(false, visible)"
          v-if="deviceImportList.length"
          >注册</b-button
        >
        <b-button @click="onCancel(visible)">取消</b-button>
      </template>
      <template v-else>
        <b-button @click="handleClickDownLoadFailRecord">下载</b-button>
        <b-button @click="onCancel(visible)">取消</b-button>
      </template>
    </template>
    <template #details>
      <Form
        :model="formState"
        ref="basicRef"
        :label-col="{
          style: {
            width: '220px',
          },
        }"
        :wrapper-col="{ span: 16 }"
        autocomplete="off"
        labelAlign="right"
      >
        <FormItem
          label="注册名称"
          name="registerName"
          :rules="[{ required: true, message: '请输入注册名称' }]"
        >
          <Input v-model:value="formState.registerName"></Input>
        </FormItem>
        <FormItem label="" name="">
          <div class="upload">
            <div>
              请下载表格模板，在填写完成后，点击导入文件，完成文件上传：
            </div>
            <div class="import">
              <!-- :headers="upload.headers"
                :action="upload.url"
                @change="handleChange" -->
              <UploadDragger
                v-model:fileList="fileList"
                name="file"
                :beforeUpload="beforeUpload"
                :customRequest="customRequest"
                ><p class="ant-upload-drag-icon">
                  <CloudUploadOutlined />
                </p>
                <p class="ant-upload-text">
                  将文件拖到此处，或
                  <span class="link">点击上传</span>
                </p>
              </UploadDragger>
            </div>
            <div>
              将文件拖到此处，或点击上传 ，仅允许导入xls、xlsx格式文件。
              <span class="link" @click="downloadTemp">下载模板</span>
            </div>
          </div>
        </FormItem>
      </Form>
    </template>
    <template #table>
      <div class="table_btn">
        <div
          :class="[
            'success',
            {
              active: isSuccess === 1,
            },
          ]"
          @click="onChangUpload(1)"
        >
          校验成功
        </div>
        <div
          :class="[
            'success',
            {
              active: isSuccess === 0,
            },
          ]"
          @click="onChangUpload(0)"
        >
          校验失败
        </div>
      </div>
      <div class="register">
        <ProTable
          ref="uploadRef"
          hideSearch
          :fetchListApi="_getUploadList"
          :columns="_uploadColumns"
        ></ProTable>
      </div>
    </template>
  </FormModal4>
</template>

<script setup lang="ts">
import { computed, ref, resolveDirective, watch } from 'vue';
import { useUserStore } from '@/stores/modules';
import { CloudUploadOutlined } from '@ant-design/icons-vue';
import {
  Descriptions,
  DescriptionsItem,
  Form,
  FormItem,
  FormItemRest,
  Input,
  Modal,
  Space,
  Table,
  UploadDragger,
  message,
} from 'ant-design-vue';
import dayjs from 'dayjs';
import { saveAs } from 'file-saver';
import { ProFormProps } from '@/components/ProForm';
import { ProTable, ProTableProps } from '@/components/ProTable/index';
import { useFormModal } from '@/hooks/formModal';
import { listToEnum } from '@/utils/utils';
import { getDictType } from '@/api/monitor';
import { saveRecord } from '@/api/notice';
import {
  batchDelete,
  deviceImportCheck,
  downloadFailRecord,
  downloadTemplate,
  getPushCompare,
  getPushDetail,
  getPushTotalInfo,
  getRegisterInfo,
  getRegisterList,
  handlePublish,
  handleRegister,
  importFile,
  registerMerge,
} from '@/api/push';

const typeEnum: any = ref();
const dictInit = () => {
  getDictType('device_operate_type').then((res) => {
    typeEnum.value = listToEnum(res.data as any, 'dictLabel', 'dictCode');
  });
};

dictInit();

const { token } = useUserStore();

const tableRef = ref();
const _getList = async (params: any) => {
  if (params.createTime) {
    params.startTime = dayjs(params.createTime[0])
      .startOf('day')
      .format('YYYY-MM-DD HH:mm:ss');
    params.endTime = dayjs(params.createTime[0])
      .endOf('day')
      .format('YYYY-MM-DD HH:mm:ss');
  }
  const res: any = await getRegisterList(params);
  const { rows, total } = res;
  const newRows = rows.map((item: any) => {
    return {
      ...item,
      registerUser: [...new Set(item.registerUser.split(','))].join(','),
      registerRate: isDecimalZeroZero(item.registerRate)
        ? parseInt(item.registerRate) + '%'
        : item.registerRate + '%',
      publishRate: isDecimalZeroZero(item.publishRate)
        ? parseInt(item.publishRate) + '%'
        : item.publishRate + '%',
    };
  });

  return {
    rows: newRows,
    total,
  };
};

const isDecimalZeroZero = (value: any) => {
  return /^\d+(\.\d{2})?$/.test(value) && /(\.00)$/.test(value);
};

const columns = computed<ProTableProps['columns']>(() => [
  {
    title: '创建时间',
    dataIndex: 'createTime',
    isTime: true,
  },
  {
    title: '注册名称',
    dataIndex: 'registerName',
    hideInSearch: true,
  },
  {
    title: '注册人',
    dataIndex: 'registerUser',
  },
  {
    title: '注册总数',
    dataIndex: 'registerTotalNum',
    hideInSearch: true,
  },
  {
    title: '注册成功数',
    dataIndex: 'registerSuccessNum',
    hideInSearch: true,
  },
  {
    title: '注册失败数',
    dataIndex: 'registerFailNum',
    hideInSearch: true,
  },
  {
    title: '待注册数量',
    dataIndex: 'stayRegisterNum',
    hideInSearch: true,
  },
  {
    title: '注册进度',
    dataIndex: 'registerRate',
    hideInSearch: true,
  },
  {
    title: '操作',
    dataIndex: 'operation',
    width: 220,
    hideInSearch: true,
  },
]);

const selectKeys = ref<number[]>([]);
const rowSelection = computed<ProTableProps['rowSelection']>(() => {
  return {
    selectedRowKeys: selectKeys.value,
    onChange(values) {
      selectKeys.value = values as number[];
    },
  };
});

const { FormModal, open } = useFormModal({
  size: 'middle',
  formProps: {
    wrapperCol: { span: 24 },
  },
});
const { FormModal: FormModal2, open: open2 } = useFormModal({
  size: 'middle',
  formProps: {
    wrapperCol: { span: 24 },
  },
});
const {
  FormModal: FormModal3,
  open: open3,
  actualHeight: actualHeight3,
} = useFormModal({
  size: 'large',
  formProps: {
    wrapperCol: { span: 24 },
  },
});

const { FormModal: FormModal4, open: open4 } = useFormModal({
  size: 'middle',
  formProps: {
    wrapperCol: { span: 24 },
  },
});

const items = computed<ProFormProps['items']>(() => [
  {
    label: '',
    type: 'number',
    field: 'details',
  },
]);

const sleep = (cb) => {
  setTimeout(() => {
    cb();
  }, 500);
};

const onDelete = () => {
  Modal.confirm({
    title: '是否删除？',
    content: `批量删除`,
    onOk: async () => {
      await batchDelete(selectKeys.value);
      sleep(() => tableRef.value.refresh());
      selectKeys.value = [];
    },
  });
};

// 下发记录
const code = ref();
const onRecord = async (record: any) => {
  code.value = record.id;
  open({
    title: '下发记录',
    size: 'middle',
    modalType: 'info',
    defaultValue: {
      ...record,
    },
    hideFooter: true,
    serviceApi: async (params: any): Promise<any> => {},
  });
};

const _getPushTotalInfo = async (params: any) => {
  const queryParams = { ...params, id: code.value };
  const res = await getPushTotalInfo(queryParams);
  return res;
};

const _columns = computed<ProTableProps['columns']>(() => [
  {
    title: '下发时间',
    dataIndex: 'pushTime',
    isTime: true,
  },
  {
    title: '下发总数',
    dataIndex: 'publishTotalNum',
    hideInSearch: true,
  },
  {
    title: '下发成功数',
    dataIndex: 'publishSuccessNum',
  },
  {
    title: '待下发数',
    dataIndex: 'stayPublishNum',
    hideInSearch: true,
  },
  {
    title: '下发失败数',
    dataIndex: 'publishFailNum',
    hideInSearch: true,
  },
  {
    title: '下发进度数',
    dataIndex: 'publishRate',
    hideInSearch: true,
  },
  {
    title: '操作',
    dataIndex: 'operation',
    width: 80,
    hideInSearch: true,
  },
]);

const onMerge = () => {
  open({
    title: '合并注册',
    modalType: 'add',
    size: 'small',
    items: [
      {
        label: '注册名称',
        type: 'input',
        field: 'registerName',
        rules: [
          { required: true, message: '注册名称不能为空', trigger: 'blur' },
        ],
        props: {
          placeholder: '请输入注册名称',
        },
      },
    ],
    serviceApi: async (params: any): Promise<any> => {
      await registerMerge({
        ids: selectKeys.value,
        ...params,
      });
      selectKeys.value = [];
      tableRef.value.refresh();
    },
  });
};

const onDetail = async (record: any) => {
  code.value = record.pushTotalId;
  open2({
    title: '下发记录',
    size: 'middle',
    modalType: 'info',
    defaultValue: {
      ...record,
    },
    hideFooter: true,
    serviceApi: async (params: any): Promise<any> => {},
  });
};

const _recordColumns = computed<ProTableProps['columns']>(() => [
  {
    title: '下发时间',
    dataIndex: 'pushTime',
    isTime: true,
  },
  {
    title: '设备序列号',
    dataIndex: 'code',
    hideInSearch: true,
  },
  {
    title: '设备授权码',
    dataIndex: 'license',
  },
  {
    title: '设备类型',
    dataIndex: 'terminalType',
    hideInSearch: true,
  },
  {
    title: '下发结果',
    dataIndex: 'pushStatus',
    hideInSearch: true,
  },
  {
    title: '在线状态',
    dataIndex: 'onlineStatus',
    hideInSearch: true,
  },
]);

const _getRecordList = async (params: any) => {
  const queryParams = { ...params, id: code.value };
  const res = await getPushDetail(queryParams);
  return res;
};
const registerStatus = ref('1');
const onView = async (record: any) => {
  code.value = record.id;
  open3({
    title: '导入详情',
    modalType: 'add',
    defaultValue: {
      ...record,
    },
    hideFooter: true,
    serviceApi: async (params: any): Promise<any> => {},
  });
};

const _importColumns = computed<ProTableProps['columns']>(() => [
  {
    title: '序号',
    dataIndex: 'index',
    hideInSearch: true,
    width: 80,
    customRender({ pageSize, pageNum, index }) {
      return (pageNum.value - 1) * pageSize.value + index + 1;
    },
  },
  {
    title: '下发时间',
    dataIndex: 'pushTime',
    hideInSearch: true,
  },
  {
    title: '设备序列号',
    dataIndex: 'code',
  },
  {
    title: '设备授权码',
    dataIndex: 'license',
  },
  {
    title: '注册地址',
    dataIndex: 'protocolAddress',
    hideInSearch: true,
  },
  {
    title: '省份代码',
    dataIndex: 'affiliation',
    hideInSearch: true,
  },
  {
    title: '设备类型',
    dataIndex: 'terminalType',
    hideInSearch: true,
  },
  {
    title: '注册状态',
    dataIndex: 'registerStatus',
    hideInSearch: true,
  },
  ...asyncColumns.value,
]);
const detailRef = ref();
const onChange = (type: any) => {
  registerStatus.value = type;
  detailRef.value.refresh();
};

const asyncColumns = computed(() => {
  if (registerStatus.value == '0') {
    return [
      {
        title: '失败原因',
        dataIndex: 'registerFailReason',
        hideInSearch: true,
      },
    ];
  } else {
    return [
      {
        title: '在线状态',
        dataIndex: 'onlineStatus',
        hideInSearch: registerStatus.value == '0',
        valueEnum: {
          '0': '离线',
          '1': '在线',
        },
      },
      {
        title: '对比结果',
        dataIndex: 'contrastStatus',
        hideInSearch: registerStatus.value == '0',
        valueEnum: {
          '2': '未对比',
          '0': '比对正确',
          '1': '信息不对',
        },
      },
    ];
  }
});

const codeKeys = ref<number[]>([]);
const codeList = ref<object[]>([]);
const codeSelection = computed<ProTableProps['rowSelection']>(() => {
  return {
    selectedRowKeys: codeKeys.value,
    onChange(values, all) {
      codeKeys.value = values as number[];
      codeList.value = all;
    },
  };
});

const _getRegisterInfo = async (params: any) => {
  const queryParams = {
    ...params,
    id: code.value,
    registerType: registerStatus.value,
  };
  const res: any = await getRegisterInfo(queryParams);
  const { total, rows } = res;
  const newRows = rows.filter(
    (item: any) => item.registerStatus !== registerStatus.value,
  );
  return {
    total,
    rows: newRows,
  };
};

// 下发配置
const handleSend = () => {
  Modal.confirm({
    title: '是否下发配置信息至设备？',
    content: `下发配置`,
    onOk: async () => {
      await handlePublish(code.value, codeKeys.value);
      sleep(() => tableRef.value.refresh());
      selectKeys.value = [];
    },
  });
};

// 下发对比
const handlePushCompare = () => {
  Modal.confirm({
    title: '是否比对下发配置信息与设备一致？',
    content: `下发比对`,
    onOk: async () => {
      await getPushCompare(code.value, codeKeys.value);
      sleep(() => tableRef.value.refresh());
      selectKeys.value = [];
    },
  });
};

// 注册救济
const handleClickRescue = (batch: boolean, visible?: any) => {
  if (!batch) {
    importFile({
      fileName: formState.value.registerName,
      successList: deviceImportList.value,
    })
      .then(async (response) => {
        if (response.code === 200) {
          const res = await handleRegister({
            registerList: deviceImportList.value,
          });
          if (res.code == 200) {
            visible.value = false;
            message.success('操作成功');
            tableRef.value.refresh();
          }
          saveRecordFn(
            deviceImportList.value,
            res,
            '推送',
            JSON.stringify({
              fileName: formState.value.registerName,
              successList: deviceImportList.value,
            }),
            '/device/register',
          );
        }
      })
      .finally(() => {
        tableRef.value.refresh();
      });
    return;
  }
  Modal.confirm({
    title: '是否对设备进行注册救济？',
    content: `注册救济`,
    onOk: async () => {
      const registerList = codeList.value.map((item: any) => {
        return {
          affiliation: item.affiliation,
          code: item.code,
          license: item.license,
          protocolAddress: item.protocolAddress,
          terminalType: item.terminalType,
        };
      });
      await handleRegister({ registerList });
      sleep(() => tableRef.value.refresh());
      selectKeys.value = [];
    },
  });
};

const saveRecordFn = async (
  data: any,
  res: any,
  operateButton: any,
  requestParam: any,
  operateUri: string,
) => {
  const list = data.map((item: any) => {
    return {
      deviceCode: item.code,
      operateModule: '推送管理/批量注册',
      requestParam,
      status: res.code == 200 ? 1 : 0,
      operateButton,
      operateType: typeEnum.value[operateButton],
      operateUri,
    };
  });

  await saveRecord({ list });
};

const contentStyle = {
  padding: '0 20px',
};

const onRegistered = () => {
  formState.value.registerName = null;
  open4({
    title: '批量注册',
    modalType: 'add',
    hideFooter: true,
    serviceApi: async (params: any): Promise<any> => {},
  });
};
const basicRef = ref();
const formState: any = ref({});
const fileList = ref([]);
const deviceImportList = ref([]);
const deviceImportFailList = ref([]);

const beforeUpload = async (file: any, fileList: any) => {
  await basicRef.value.validate();
};
// 上传
const customRequest = async (e: any) => {
  const formData = new FormData();
  formData.append('file', e.file);
  const response: any = await deviceImportCheck(formData);
  if (response.code == 200) {
    deviceImportList.value = response.successList;
    deviceImportFailList.value = response.failList;
    open4({
      title: '批量注册',
      modalType: 'add',
      items: [
        {
          label: '',
          type: 'number',
          field: 'table',
        },
      ],
      serviceApi: async (params: any): Promise<any> => {},
    });
  }
};
// 下载模板
const downloadTemp = () => {
  downloadTemplate().then((res: any) => {
    const blob = new Blob([res], {
      type: 'application/vnd.ms-excel',
    });
    saveAs(blob, `register_template_${new Date().getTime()}.xlsx`);
  });
};

const isSuccess = ref(1);
const uploadItems = computed(() => {
  if (isSuccess.value) {
    return [];
  }
  return [
    {
      title: '失败原因',
      dataIndex: 'failReason',
    },
  ];
});
const uploadRef = ref();
const onChangUpload = (type: any) => {
  isSuccess.value = type;
  uploadRef.value.refresh();
};

const _uploadColumns = computed<ProTableProps['columns']>(() => [
  {
    title: '设备序列号',
    dataIndex: 'code',
  },
  {
    title: '设备授权码',
    dataIndex: 'license',
  },
  {
    title: '注册地址',
    dataIndex: 'protocolAddress',
  },
  {
    title: '省份代码',
    dataIndex: 'affiliation',
  },
  {
    title: '设备类型',
    dataIndex: 'terminalType',
  },
  ...uploadItems.value,
]);

const _getUploadList = () => {
  const rows = isSuccess.value
    ? deviceImportList.value
    : deviceImportFailList.value;
  return {
    rows,
    total: rows.length,
  };
};

const onCancel = (visible: any) => {
  visible.value = false;
};

const handleClickDownLoadFailRecord = () => {
  downloadFailRecord(deviceImportFailList.value).then((res: any) => {
    const blob = new Blob([res], {
      type: 'application/vnd.ms-excel',
    });
    saveAs(blob, `校验失败数据_${new Date().getTime()}.xlsx`);
  });
};
</script>

<style lang="scss" scoped>
.success,
.error {
  border: 1px solid #fff;
  padding: 1px 10px;
  background: #334252;
  cursor: pointer;
  &:hover {
    color: #badeff;
    border-color: #badeff;
  }
  &.active {
    color: #badeff;
    border-color: #badeff;
  }
}
:deep(.ant-form-item-label) {
  text-align: center !important;
}
.upload {
  width: 100%;
  margin-left: 220px;
  .import {
    margin: 10px 0;
    background-color: #fff;
    border-radius: 6px;
    overflow: hidden;
  }
}
:deep(.ant-upload-text) {
  color: #c0c4cc !important;
  font-size: 12px !important;
}
:deep(.anticon-cloud-upload) {
  color: #c0c4cc !important;
}
.link {
  color: #1890ff;
  cursor: pointer;
}
:deep(.ant-upload-list) {
  display: none;
}

.table_btn {
  display: flex;
  & > div {
    margin-right: 10px;
  }
}

.record_detail {
  :deep(.ant-table) {
    height: calc(65vh - 384px);
  }
  :deep(.ant-table-body) {
    height: calc(65vh - 350px);
  }
}

.details {
  :deep(.ant-table) {
    height: calc(65vh - 210px);
  }
  :deep(.ant-table-body) {
    height: calc(65vh - 250px);
  }
}
.register {
  :deep(.ant-table) {
    height: calc(65vh - 210px);
  }
  :deep(.ant-table-body) {
    height: calc(65vh - 250px);
  }
}
</style>
